package cn.labbook.bluetooth.ammeter;


import cn.labbook.bluetooth.entity.DecryptData;
import cn.labbook.bluetooth.util.MD5Utils;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.text.SimpleDateFormat;
import java.util.Date;
@Slf4j
public class algorithm {
    public static String actorOne(String time,String address){
        String time1 = complement(time,"55");
        String address1 = complement(address,"55");
        String s = stringPlus(time1, address1);
        String s1 = byteTrans(s, 2, 3, 0, 1, 6, 7, 4, 5);
        return stringPlus(s1,"1111111111111111");
    }

    public static String actorTwo(String time,String address){
        String time1 = complement(time, "55");
        String address1 = complement(address, "55");
        String s = stringPlus(time1, address1);
        String s1 = byteTrans(s, 7, 6, 5, 4, 3, 2, 1, 0);
        return stringReduce(s1,"1011121314151617");
    }
    public static String actorThree(String time,String address){
        String time1 = complement(time, "55");
        String address1 = complement(address, "55");
        String s = stringReduce(time1, address1);
        String s1 = byteTrans(s, 7, 6, 5, 4, 3, 2, 1, 0);
        String s2 = stringReduce(s1, "0101010101010101");
        String s3 = byteTrans(s2, 4, 5, 6, 7, 0, 1, 2, 3);
        String s4 = stringPlus(s3, "1010101010101010");
        return s4;
    }



    /**
     * 单字节补位
     * */
    public static String tran(String t){
        if(t.length()==1){
            t = "0"+t;
        }
        return t;
    }
    /**
     * 字符串转字节
     * */
    public static byte[] toByteArray(String s){
        int length = s.length();
        int bl  =length/2;
        byte[] bytes2= new byte[bl];
        String sss;

        for(int q=0;q<bl;q++){
            sss = s.substring(2*q,2*(q+1));
            bytes2[q] = (byte)Integer.parseInt(sss, 16);
        }
        return bytes2;
    }
    /**
     * Double类型转String
     * */
    public static String doubleToString(Double d){
        String s2 = d.toString();
        String[] split = s2.split("\\.");
        String su = split[1];
        if(split[1].length()<4){
            for(int i=0;i<4-split[1].length();i++){
                su = su+"0";
            }
        }
        su = split[0]+su;
        return su;
    }
    /**
     * 字符串转字节
     * */
    public static byte[] toByteArray1(String s){
        int length = s.length();
        int bl  =length;
        byte[] bytes2= new byte[bl];
        String sss;

        for(int q=0;q<bl;q++){
            sss = s.substring(q,(q+1));
            bytes2[q] = (byte)Integer.parseInt(sss, 16);
        }
        return bytes2;
    }

    /**
     * 字节转字符串
     * */
    public static String toString(byte[] bytes){
        String s = "";
        for (byte b : bytes) {
            String s1 = Integer.toHexString(b & 0xff);
            if(s1.length()==1){
                s1 = "0".concat(s1);
            }
            s = s.concat(s1);
        }
        return s;
    }
    /**
     * 16进制字符串相加
     * */
    public static String stringPlus(String s1,String s2){
        if(s1.length()==1){
            s1 = "0".concat(s1);
        }
        byte[] bytes = toByteArray(s1);
        byte[] bytes1 = toByteArray(s2);
        StringBuffer buffer = new StringBuffer();
        for (int i = 0;i<bytes.length;i++){
            int d = ((bytes[i] ) + (bytes1[i]))&0xff;
            buffer.append (tran(Integer.toHexString(Math.abs(d))));
        }
        return buffer.toString();
    }
    /**
     * 16进制字符串相减
     * */
    public static String stringReduce(String s1,String s2){
        if(s1.length()==1){
            s1 = "0".concat(s1);
        }
        byte[] bytes = toByteArray(s1);
        byte[] bytes1 = toByteArray(s2);
        StringBuffer buffer = new StringBuffer();
        for (int i = 0;i<bytes.length;i++){
            int d = ((bytes[i]) - (bytes1[i]))&0xff;
            buffer.append (tran(Integer.toHexString(Math.abs(d))));
        }
        return buffer.toString();
    }
    /**
     * 16进制字符串换位
     * */
    public static String byteTrans(String s,int i,int i1,int i2,int i3,int i4,int i5,int i6,int i7){
        byte[] bytes = toByteArray(s);
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(tran(Integer.toHexString(bytes[i]&0xff)));
        stringBuffer.append(tran(Integer.toHexString(bytes[i1]&0xff)));
        stringBuffer.append(tran(Integer.toHexString(bytes[i2]&0xff)));
        stringBuffer.append(tran(Integer.toHexString(bytes[i3]&0xff)));
        stringBuffer.append(tran(Integer.toHexString(bytes[i4]&0xff)));
        stringBuffer.append(tran(Integer.toHexString(bytes[i5]&0xff)));
        stringBuffer.append(tran(Integer.toHexString(bytes[i6]&0xff)));
        stringBuffer.append(tran(Integer.toHexString(bytes[i7]&0xff)));
        return stringBuffer.toString();
    }

    /**
     * 16进制字符串补足
     * */
    public static String complement(String s,String c){
        int i = 8-s.length()/2;
        String result = c;
        for(int i1=0;i1<i-1;i1++){
            result = result.concat(c);
        }
        result = result.concat(s);
        return result;
    }

    /**
     * 纯加密
     * */
    public static byte[] encrypt(byte[] sSrc, String sKey) throws Exception {
        if (sKey == null) {
            System.out.print("Key为空null");
            return null;
        }
        // 判断Key是否为16位
        if (sKey.length() != 16) {
            System.out.print("Key长度不是16位");
            return null;
        }
        byte[] raw = sKey.getBytes();
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式"
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(sSrc);
        String str = "";
//        for (byte b : encrypted) {
//            String s1 = Integer.toHexString(b & 0xff);
//            str = str.concat(s1);
//        }
//        System.out.println(str);
        return encrypted;
    }

    /**
     * 加密（结果有各字节加33操作）
     * */
    public static String encryptResult(byte[] sSrc, String sKey) throws Exception {
        byte[] encrypt = encrypt(sSrc, sKey);

        byte[] bb = new byte[encrypt.length];
        for (int i = 0; i < encrypt.length; i++) {
            bb[i] = (byte) ((encrypt[i] & 0xff) + 0x33);
        }
        String str = "";
        for (byte b : bb) {
            String s1 = Integer.toHexString(b & 0xff);
            if(s1.length()==1){
                s1 ="0".concat(s1);
            }
            str = str.concat(s1);
        }
        return str;
    }



    /**
     * 纯解密
     * */
    public static byte[] decrypt(byte[] sSrc, String sKey) throws Exception {
        try {
            //判断Key是否正确
            if (sKey == null) {
                System.out.print("Key为空null");
                return null;
            }
            // 判断Key是否为16位
            if (sKey.length() != 16) {
                System.out.print("Key长度不是16位");
                return null;
            }
            byte[] raw = sKey.getBytes();
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            try {
                return cipher.doFinal(sSrc);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * 解密获取电表数据（有各字节减33操作）
     * */
    public static byte[] decryptResult(String content, String key) throws Exception {
        byte[] bytes = algorithm.toByteArray(content);
        byte[] bb = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            bb[i] = (byte) ((bytes[i] & 0xff) - 0x33);
        }
        byte[] decrypt = decrypt(bb, key);
//        print(decrypt);

        return decrypt;
    }
    /*
     * 将时间戳转换为时间
     */
    public static String stampToDate(long l) {
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        long lt = l;
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }
    /*
     * 将时间转换为时间戳
     */
    public static long dateToStamp(String s) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = null;
        try {
            date = simpleDateFormat.parse(s);
            return date.getTime();
        } catch (java.text.ParseException e) {
            // TODO Auto-generated catch block

            e.printStackTrace();
            return -1;
        }
    }
    //计算两个时间戳间隔多少秒
    public static long equation(Date startTime, Date endTime) {
        long day=(startTime.getTime()-endTime.getTime());
        return day;
    }

    /**
     * 截取解密电表数据
     * */
    public static DecryptData byteToData(byte[] decrypt){
        log.info("抄到的未处理的原始数据================================:"+toString(decrypt));
        byte[] var1 = new byte[7];
        System.arraycopy(decrypt, 0, var1, 0, 7);
//        print(var1);

        byte[] var2 = new byte[8];
        System.arraycopy(decrypt, 7, var2, 0, 8);
//        print(var2);

        byte[] var3 = new byte[24];
        System.arraycopy(decrypt, 15, var3, 0, 24);
//        print(var3);

        byte[] var4 = new byte[16];
        System.arraycopy(decrypt, 39, var4, 0, 16);
//        print(var4);

        byte[] var5 = new byte[64];
        System.arraycopy(decrypt, 55, var5, 0, 64);
//        print(var5);

        byte[] var6 = new byte[1];
        System.arraycopy(decrypt, 119, var6, 0, 1);
//        print(var6);

        byte[] var7 = new byte[1];
        System.arraycopy(decrypt, 120, var7, 0, 1);
//        print(var7);

        byte[] var8 = new byte[4];
        System.arraycopy(decrypt, 121, var8, 0, 4);
//        print(var8);

        byte[] var9 = new byte[24];
        System.arraycopy(decrypt, 125, var9, 0, 24);
//        print(var9);

        byte[] var10 = new byte[4];
        System.arraycopy(decrypt, 149, var10, 0, 4);
//        print(var10);

        byte[] var11 = new byte[23];
        System.arraycopy(decrypt, 153, var11, 0, 23);
//        print(var11);

        byte[] var12 = new byte[2];
        System.arraycopy(decrypt, 176, var12, 0, 2);
//        print(var12);

        byte[] var13 = new byte[2];
        System.arraycopy(decrypt, 178, var13, 0, 2);
//        print(var13);

        byte[] var14 = new byte[4];
        System.arraycopy(decrypt, 180, var14, 0, 4);
//        print(var14);

        byte[] var15 = new byte[1];
        System.arraycopy(decrypt, 184, var15, 0, 1);
//        print(var15);

        byte[] var16 = new byte[1];
        System.arraycopy(decrypt, 185, var16, 0, 1);
//        print(var16);

        byte[] var17= new byte[1];
        System.arraycopy(decrypt, 186, var17, 0, 1);
//        print(var17);

//        String str = "";
//        for (byte b : decrypt) {
//            String s1 = Integer.toHexString(b & 0xff);
//            str = str.concat(s1).concat(" ");
//        }
        DecryptData decryptData = new DecryptData();
        decryptData.setTime(toString(column(var1)));

        String s = toString(column(var2));
        log.info("8字节电表状态字================================{}",s);
        decryptData.setStatus(s);
        log.info("8字节电表状态字2================================{}",decryptData.getStatus());
        decryptData.setFestival(toString(column(var3)));
        decryptData.setRatePrice(toString(column(var4)));
        decryptData.setLadderPrice(toString(column(var5)));
        decryptData.setRateNo(toString(column(var6)));
        decryptData.setLadderNo(toString(column(var7)));

        StringBuffer stringBuilder=new StringBuffer(toString(column(var8)));
        stringBuilder.insert(4,".");
        decryptData.setElectrovalence(stringBuilder.toString());

        decryptData.setElectricityData(toString(column(var9)));

        StringBuffer stringBuilder1=new StringBuffer(toString(column(var10)));
        stringBuilder1.insert(6,".");
        decryptData.setBalance(stringBuilder1.toString());

        decryptData.setLastBuy(toString(column(var11)));
        decryptData.setTemperature(toString(column(var12)));
        decryptData.setVoltage(toString(column(var13)));
        decryptData.setBatteryTime(toString(column(var14)));
        decryptData.setEncryptionS(toString(column(var15)));
        decryptData.setEncryptionP(toString(column(var16)));
        decryptData.setKeyStatus(toString(column(var17)));
        decryptData.setVar17(toString(decrypt));

        log.info("decryptData========================={}", decryptData.toString());

        return decryptData;
    }
//    public static byte[] padding(byte[] bytes,int l){
//        int i = 16;
//        int s = i-l%16;
//        int i1 = 16;
//        i-(bytes.length)%i
//    }

    public static void print(byte[] bytes) {
        String sss1 = "";
        for (byte b : bytes) {
            String s1 = Integer.toHexString(b & 0xff);
            sss1 = sss1.concat(s1).concat(" ");
        }
    }



    public static byte[] column(byte[] b1){
        for (int start = 0, end = b1.length - 1; start < end; start++, end--) {
            byte temp = b1[end];
            b1[end] = b1[start];
            b1[start] = temp;
        }
        return b1;
    }

    public static String getTime(){
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddEEhhmmss");
        Date date = new Date();
        String format1 = format.format(date);
        log.info("format1:"+format1);
        if(format1.indexOf("星期一")>0){
            format1 = format1.replace("星期一","01");
        }else if(format1.indexOf("星期二")>0){
            format1 = format1.replace("星期二","02");
        }else if(format1.indexOf("星期三")>0){
            format1 = format1.replace("星期三","03");
        }else if(format1.indexOf("星期四")>0){
            format1 = format1.replace("星期四","04");
        }else if(format1.indexOf("星期五")>0){
            format1 = format1.replace("星期五","05");
        }else if(format1.indexOf("星期六")>0){
            format1 = format1.replace("星期六","06");
        }else if(format1.indexOf("星期日")>0){
            format1 = format1.replace("星期日","00");
        }
        if(format1.indexOf("Mon")>0){
            format1 = format1.replace("Mon","01");
        }else if(format1.indexOf("Tue")>0){
            format1 = format1.replace("Tue","02");
        }else if(format1.indexOf("Wed")>0){
            format1 = format1.replace("Wed","03");
        }else if(format1.indexOf("Thu")>0){
            format1 = format1.replace("Thu","04");
        }else if(format1.indexOf("Fri")>0){
            format1 = format1.replace("Fri","05");
        }else if(format1.indexOf("Sat")>0){
            format1 = format1.replace("Sat","06");
        }else if(format1.indexOf("Sun")>0){
            format1 = format1.replace("Sun","00");
        }
        String substring = format1.substring(2, format1.length());
        return substring;
    }

    public static String getTimeBack(){
        SimpleDateFormat format = new SimpleDateFormat("ssmmHHEEddMMyy");
        Date date = new Date();
        String format1 = format.format(date);
        log.info("format1:"+format1);
        if(format1.indexOf("星期一")>0){
            format1 = format1.replace("星期一","01");
        }else if(format1.indexOf("星期二")>0){
            format1 = format1.replace("星期二","02");
        }else if(format1.indexOf("星期三")>0){
            format1 = format1.replace("星期三","03");
        }else if(format1.indexOf("星期四")>0){
            format1 = format1.replace("星期四","04");
        }else if(format1.indexOf("星期五")>0){
            format1 = format1.replace("星期五","05");
        }else if(format1.indexOf("星期六")>0){
            format1 = format1.replace("星期六","06");
        }else if(format1.indexOf("星期日")>0){
            format1 = format1.replace("星期日","00");
        }
        if(format1.indexOf("Mon")>0){
            format1 = format1.replace("Mon","01");
        }else if(format1.indexOf("Tue")>0){
            format1 = format1.replace("Tue","02");
        }else if(format1.indexOf("Wed")>0){
            format1 = format1.replace("Wed","03");
        }else if(format1.indexOf("Thu")>0){
            format1 = format1.replace("Thu","04");
        }else if(format1.indexOf("Fri")>0){
            format1 = format1.replace("Fri","05");
        }else if(format1.indexOf("Sat")>0){
            format1 = format1.replace("Sat","06");
        }else if(format1.indexOf("Sun")>0){
            format1 = format1.replace("Sun","00");
        }
//        String substring = format1.substring(2, format1.length());
        return format1;
    }

    public static void main(String[] args) throws Exception {
        String s = MD5Utils.string2MD5("123456");
        System.out.println(s);
    }

}
